﻿#ifndef XQFILETABLEWIDGET_H
#define XQFILETABLEWIDGET_H
//图片名字过滤器
#define IMAGENAMEFILTERS { "*.png","*.jpg","*.ico","*.bmp","*.gif","*.tif","*.tga" }
#define FILEMD5 (Qt::UserRole+1) //文件md5值
#define FILEEXIST (Qt::UserRole+1) //文件是否存在
#include<QTableWidget>
#include<QFileInfo>
#include<QMap>
//文件基本信息
struct fileInfo
{
	QString name;//名字
	QString file_path;//远程或本地路径
	QString md5;//文件的md5值
	size_t  fileSize;//文件大小
};
class QFileSystemWatcher;
class QMenu;
//文件表格小部件
class XQFileTableWidget:public QTableWidget
{
	Q_OBJECT
public:
	enum Type
	{
		icon,//图标
		name,//名字
		size,//大小
		locality,//本地
		cloud//云端
	};
	XQFileTableWidget(QWidget* parent = nullptr);
	~XQFileTableWidget();
	//获取监视目录
	QString dirPath()const;
	//获取本地文件列表
	QStringList localityFiles();
	//获取右键菜单
	QMenu* menu();
	//获取表格文件大小总和
	size_t tableFileSizeSum();
	//获取单文件最大大小
	size_t fileMaxSize();
	//获取总文件最大大小
	size_t fileSumMaxSize();
	//是否可以修改文件名
	bool changeNameFlag();
	//是否在本地存在
	bool isLocalFile(int row)const;
	//是否是远程文件
	bool isRemoteFile(int row)const;
	//获取名字所在行
	int nameToRow(const QString& name)const;
	//根据md5值获取所在行
	int md5ToRow(const QString& md5)const;
	//根据行获取md5值
	QString rowToMd5(int row)const;
public slots:
	//设置水平标题
	void setHorizontalHeading(const QStringList& list);
	//设置监视目录
	void setDirPath(const QString& dir);
	//设置过滤器
	void setNameFilters(const QStringList& Filters);
	//设置文件最大大小
	void setFileMaxSize(const size_t size);
	//设置总文件最大大小
	void setFileSumMaxSize(const size_t size);
	//设置禁止修改文件名字
	void setChangeNameFlag(bool flag);
	//添加文件
	size_t addFile(const QStringList& fileList);
	//删除本地文件
	size_t removeFile(const QStringList& fileList);
	//删除本地文件
	void removeFile(int row);
	//删除所有行只留下标题
	void removeAllRow();
	//添加云端文件
	void addCloudFile(const QString& name, const QString& md5,size_t size);
	//删除云端文件
	void removeCloudFile(const QString& md5);
	//返回远程文件信息的引用
	fileInfo& cloudFile(const QString& md5);
	//清空云端文件
	void clearCloudFile();
	//打开选中的文件
	void openFile();
	//设置右键菜单
	void setMenu(QMenu* menu);
	//设置进度条
	void setProgressBar(int row, Type LocaType, size_t val, size_t maxSize, const QString& text=QString());
	//本地文件改名
	void renamelocalFile(QTableWidgetItem* item);
	//远程文件改名
	void renameremoteFile(QTableWidgetItem* item);
	//刷新文件列表
	void updataTabel();
	//复制链接地址到剪切板
	void copyLinkPath(int row);
signals://信号
	//表格文件变化
	void tableFileChange();
	//远程文件改名
	void renameRemoteFile(XQFileTableWidget* widget,fileInfo* info,const QString& newName);
	//远程删除文件
	void removeRemoteFile(XQFileTableWidget* widget, fileInfo* info);
	//上传本地文件
	void upLocalFile(XQFileTableWidget* widget, fileInfo* info);
	//下载远程文件
	void downRemoteFile(XQFileTableWidget* widget, fileInfo* info);
protected:
	//初始化
	void init();
	//UI初始化
	void UIInit();
	//右键菜单初始化
	void menuInit();
protected:
	//table文件列表初始化重新加载目录文件
	void tableFileInit();
	//监视目录变化
	void WatcherInit();
	//文件改变
	void fileChange();
	//获取表格的文件名字列表
	QStringList tableFileName();
	//插入本地文件到表格
	virtual void insertLocalFileToTable(const fileInfo& info);
	//插入云端文件到表格
	virtual void insertCloudFileToTable(const fileInfo& info);
	//设置列表宽度完全显示
	void SetColumnWidth(int index);
protected:
	//多线程方式copy文件
	void copyFileThreadInit(const QString& name, const QString& newName);
	//多线程开始拷贝
	void copyFileThreadStart(const QString& name, const QString& newName, const size_t fileSize);
	//多线程拷贝进度
	void copyFileThreadProgress(const QString& name, const QString& newName, size_t currentSize, const size_t fileSize);
	//多线程拷贝结束
	void copyFileThreadFinish(const QString& name, const QString& newName, const size_t fileSize);
protected:
	//拖拽进入事件
	void dragEnterEvent(QDragEnterEvent* event) override;
	//拖拽完成事件
	void dropEvent(QDropEvent* event) override;
	//窗口大小改变事件
	void resizeEvent(QResizeEvent* event)override;
	//右键菜单事件
	void contextMenuEvent(QContextMenuEvent* event) override;
	//窗口显示时事件
	void showEvent(QShowEvent* event)override;
private:
	bool m_changeNameFlag = true;
	QFileSystemWatcher* m_Watcher = nullptr;//正在监视目录
	QString m_DirPath;//需要监视的目录
	QStringList m_nameFilters;//设置过滤器
	QList<bool> m_sorts;//排序情况
	QMenu* m_menu=nullptr;//右键菜单
	size_t m_fileMaxSize = SIZE_MAX;//限制的文件大小字节
	size_t m_fileSumMaxSize = SIZE_MAX;//限制的总文件大小字节
	QMap<QString, QTableWidgetItem*> m_items;//文件路径映射单元格的指针 主要用在进度条能快速找到
	QMap<QString, fileInfo> m_cloudFile;//云端文件
	QMap<QString, fileInfo> m_localFile;//本地文件
};

#endif // !XFileTableWidget_H
